<div x-data="{
        commandItems: {
            suggestions : [
                {
                    title: 'Calendar',
                    value: 'calendar',
                    icon: '<svg xmlns=\'http://www.w3.org/2000/svg\' width=\'24\' height=\'24\' viewBox=\'0 0 24 24\' fill=\'none\' stroke=\'currentColor\' stroke-width=\'2\' stroke-linecap=\'round\' stroke-linejoin=\'round\' class=\'w-4 h-4 mr-2\'><rect width=\'18\' height=\'18\' x=\'3\' y=\'4\' rx=\'2\' ry=\'2\'></rect><line x1=\'16\' x2=\'16\' y1=\'2\' y2=\'6\'></line><line x1=\'8\' x2=\'8\' y1=\'2\' y2=\'6\'></line><line x1=\'3\' x2=\'21\' y1=\'10\' y2=\'10\'></line></svg>',
                    default: true,
                },
                {
                    title: 'Search Emoji',
                    value: 'emoji',
                    icon: '<svg xmlns=\'http://www.w3.org/2000/svg\' width=\'24\' height=\'24\' viewBox=\'0 0 24 24\' fill=\'none\' stroke=\'currentColor\' stroke-width=\'2\' stroke-linecap=\'round\' stroke-linejoin=\'round\' class=\'w-4 h-4 mr-2\'><circle cx=\'12\' cy=\'12\' r=\'10\'></circle><path d=\'M8 14s1.5 2 4 2 4-2 4-2\'></path><line x1=\'9\' x2=\'9.01\' y1=\'9\' y2=\'9\'></line><line x1=\'15\' x2=\'15.01\' y1=\'9\' y2=\'9\'></line></svg>',
                    default: true,
                },
                {
                    title: 'Calculator',
                    value: 'calculator',
                    icon: '<svg xmlns=\'http://www.w3.org/2000/svg\' width=\'24\' height=\'24\' viewBox=\'0 0 24 24\' fill=\'none\' stroke=\'currentColor\' stroke-width=\'2\' stroke-linecap=\'round\' stroke-linejoin=\'round\' class=\'w-4 h-4 mr-2\'><rect width=\'16\' height=\'20\' x=\'4\' y=\'2\' rx=\'2\'></rect><line x1=\'8\' x2=\'16\' y1=\'6\' y2=\'6\'></line><line x1=\'16\' x2=\'16\' y1=\'14\' y2=\'18\'></line><path d=\'M16 10h.01\'></path><path d=\'M12 10h.01\'></path><path d=\'M8 10h.01\'></path><path d=\'M12 14h.01\'></path><path d=\'M8 14h.01\'></path><path d=\'M12 18h.01\'></path><path d=\'M8 18h.01\'></path></svg>',
                    default: true,
                }
            ],
            settings: [
                {
                    title: 'Profile',
                    value: 'profile',
                    icon: '<svg xmlns=\'http://www.w3.org/2000/svg\' width=\'24\' height=\'24\' viewBox=\'0 0 24 24\' fill=\'none\' stroke=\'currentColor\' stroke-width=\'2\' stroke-linecap=\'round\' stroke-linejoin=\'round\' class=\'w-4 h-4 mr-2\'><path d=\'M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2\'></path><circle cx=\'12\' cy=\'7\' r=\'4\'></circle></svg>',
                    right: '⌘P',
                    default: true,
                },
                {
                    title: 'Billing',
                    value: 'billing',
                    icon: '<svg xmlns=\'http://www.w3.org/2000/svg\' width=\'24\' height=\'24\' viewBox=\'0 0 24 24\' fill=\'none\' stroke=\'currentColor\' stroke-width=\'2\' stroke-linecap=\'round\' stroke-linejoin=\'round\' class=\'w-4 h-4 mr-2\'><rect width=\'20\' height=\'14\' x=\'2\' y=\'5\' rx=\'2\'></rect><line x1=\'2\' x2=\'22\' y1=\'10\' y2=\'10\'></line></svg>',
                    right: '⌘B',
                    default: true,
                },
                {
                    title: 'Settings',
                    value: 'settings',
                    icon: '<svg xmlns=\'http://www.w3.org/2000/svg\' width=\'24\' height=\'24\' viewBox=\'0 0 24 24\' fill=\'none\' stroke=\'currentColor\' stroke-width=\'2\' stroke-linecap=\'round\' stroke-linejoin=\'round\' class=\'w-4 h-4 mr-2\'><path d=\'M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z\'></path><circle cx=\'12\' cy=\'12\' r=\'3\'></circle></svg>',
                    right: '⌘S',
                    default: true,
                },
                {
                    title: 'Keyboard Settings',
                    value: 'keyboard-settngs',
                    icon: '<svg xmlns=\'http://www.w3.org/2000/svg\' width=\'24\' height=\'24\' viewBox=\'0 0 24 24\' fill=\'none\' stroke=\'currentColor\' stroke-width=\'2\' stroke-linecap=\'round\' stroke-linejoin=\'round\' class=\'w-4 h-4 mr-2\'><rect width=\'20\' height=\'16\' x=\'2\' y=\'4\' rx=\'2\' ry=\'2\'></rect><path d=\'M6 8h.001\'></path><path d=\'M10 8h.001\'></path><path d=\'M14 8h.001\'></path><path d=\'M18 8h.001\'></path><path d=\'M8 12h.001\'></path><path d=\'M12 12h.001\'></path><path d=\'M16 12h.001\'></path><path d=\'M7 16h10\'></path></svg>',
                    right: '⌘K',
                    default: false,
                },
            ]
        },
        commandItemsFiltered: [],
        commandItemActive: null,
        commandItemSelected: null,
        commandId: $id('command'),
        commandSearch: '',
        commandSearchIsEmpty() {
            return this.commandSearch.length == 0;
        },
        commandItemIsActive(item) {
            return this.commandItemActive && this.commandItemActive.value==item.value;
        },
        commandItemActiveNext(){
            let index = this.commandItemsFiltered.indexOf(this.commandItemActive);
            if(index < this.commandItemsFiltered.length-1){
                this.commandItemActive = this.commandItemsFiltered[index+1];
                this.commandScrollToActiveItem();
            }
        },
        commandItemActivePrevious(){
            let index = this.commandItemsFiltered.indexOf(this.commandItemActive);
            if(index > 0){
                this.commandItemActive = this.commandItemsFiltered[index-1];
                this.commandScrollToActiveItem();
            }
        },
        commandScrollToActiveItem(){
            if(this.commandItemActive){
                activeElement = document.getElementById(this.commandItemActive.value + '-' + this.commandId)
                if(!activeElement) return;
                
                newScrollPos = (activeElement.offsetTop + activeElement.offsetHeight) - this.$refs.commandItemsList.offsetHeight;
                if(newScrollPos > 0){
                    this.$refs.commandItemsList.scrollTop=newScrollPos;
                } else {
                    this.$refs.commandItemsList.scrollTop=0;
                }
            }
        },
        commandSearchItems() {
            if(!this.commandSearchIsEmpty()){
                searchTerm = this.commandSearch.replace(/\*/g, '').toLowerCase();
                this.commandItemsFiltered = this.commandItems.filter(item => item.title.toLowerCase().startsWith(searchTerm));
                
                this.commandScrollToActiveItem();
            } else {
                this.commandItemsFiltered = this.commandItems.filter(item => item.default);
            }
            this.commandItemActive = this.commandItemsFiltered[0];
        },
        commandShowCategory(item, index){
            if(index == 0) return true;
            if(typeof this.commandItems[index-1] === 'undefined') return false;
            return item.category != this.commandItems[index-1].category;
        },
        commandCategoryCapitalize(string){
            return string.charAt(0).toUpperCase() + string.slice(1);
        },
        commandItemsReorganize(){
            commandItemsOriginal = this.commandItems;
            keys = Object.keys(this.commandItems);
            this.commandItems = [];
            keys.forEach((key, index) => {
                for(i=0; i<commandItemsOriginal[key].length; i++){
                    commandItemsOriginal[key][i].category = key;
                    this.commandItems.push( commandItemsOriginal[key][i] );
                }
            });
        }
    }" x-init="
        commandItemsReorganize();
        commandSearchItems();
        $watch('commandSearch', value => commandSearchItems());
        $watch('commandItemSelected', function(item){
            if(item){
                console.log('item:', item);
            }
        });
    " 
    @keydown.down="event.preventDefault(); commandItemActiveNext();" 
    @keydown.up="event.preventDefault(); commandItemActivePrevious()" 
    @keydown.enter="commandItemSelected=commandItemActive;" 
    class="flex min-h-[370px] justify-center w-full max-w-xl items-start" x-cloak>
    <div class="flex flex-col w-full h-full overflow-hidden bg-white border rounded-lg shadow-md">
        <div class="flex items-center px-3 border-b">
            <svg class="w-4 h-4 mr-0 text-neutral-400 shrink-0" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" x2="16.65" y1="21" y2="16.65"></line></svg>
            <input type="text" x-ref="commandInput" x-model="commandSearch" class="flex w-full px-2 py-3 text-sm bg-transparent border-0 rounded-md outline-none focus:outline-none focus:ring-0 focus:border-0 placeholder:text-neutral-400 h-11 disabled:cursor-not-allowed disabled:opacity-50" placeholder="Type a command or search..." autocomplete="off" autocorrect="off" spellcheck="false">
        </div>
        <div x-ref="commandItemsList" class="max-h-[320px] overflow-y-auto overflow-x-hidden">
            <template x-for="(item, index) in commandItemsFiltered" :key="'item-' + index">

                <div class="pb-1 space-y-1">
                    <template x-if="commandShowCategory(item, index)">
                        <div class="px-1 overflow-hidden text-gray-700">
                            <div class="px-2 py-1 my-1 text-xs font-medium text-neutral-500" x-text="commandCategoryCapitalize(item.category)"></div>
                        </div>
                    </template>
                    
                    <template x-if="(item.default && commandSearchIsEmpty()) || !commandSearchIsEmpty()">
                        <div class="px-1">
                            <div :id="item.value + '-' + commandId" @click="commandItemSelected=item" @mousemove="commandItemActive=item" :class="{ 'bg-neutral-100 text-gray-900' : commandItemIsActive(item) }" class="relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50">
                                <span x-html="item.icon"></span>
                                <span x-text="item.title"></span>
                                <template x-if="item.right">
                                    <span class="ml-auto text-xs tracking-widest text-muted-foreground" x-text="item.right"></span>
                                </template>
                            </div>
                        </div>
                    </template>
                </div>

            </template>
        </div>
    </div>
</div>